﻿using CTP.CRM.Core.Redis;
using FreeRedis;
using Microsoft.Extensions.Logging;
using System.Diagnostics.CodeAnalysis;
using Volo.Abp.Localization;

namespace CTP.CRM.Core.Localization
{
    //
    // 摘要:
    //     动态多语言扩展配置
    public static class CTPLocalizationExtensions
    {
        private static readonly Dictionary<string, CTPRedisLocalizationResource> Resources = new Dictionary<string, CTPRedisLocalizationResource>();

        //
        // 摘要:
        //     每个项目配置一次
        //     从配置中读取信息，示例：
        //     "Language": {
        //     "SystemName": "my",
        //     "Index": 0,
        //     "KeyPrefix": "language"
        //     }
        //     var section = configuration.GetSection("Language");
        //     options.AddRedisResource(section);
        //
        // 参数:
        //   localizationResource:
        //
        //   section:
        //
        // 类型参数:
        //   TLocalizationResource:
        public static TLocalizationResource AddRedisResource<TLocalizationResource>([NotNull] this TLocalizationResource localizationResource, IConfigurationSection section) where TLocalizationResource : LocalizationResourceBase
        {
            string value = section.GetValue<string>("SystemName");
            int value2 = section.GetValue<int>("Index");
            string value3 = section.GetValue<string>("KeyPrefix");
            ArgumentNullException.ThrowIfNull(value, "systemName");
            ArgumentNullException.ThrowIfNull(value3, "keyPrefix");
            return localizationResource.AddRedisResource(value, value2, value3);
        }

        //
        // 摘要:
        //     通过 Redis 实现动态多语言。每个项目配置一次。
        //
        // 参数:
        //   localizationResource:
        //     语言资源处理器
        //
        //   systemName:
        //     子系统在主数据中心的名称
        //
        //   dbIndex:
        //     key 存储数据库位置
        //
        //   keyPrefix:
        //     key前缀，以主数据中心配置为准
        //
        // 类型参数:
        //   TLocalizationResource:
        public static TLocalizationResource AddRedisResource<TLocalizationResource>([NotNull] this TLocalizationResource localizationResource, [NotNull] string systemName, int dbIndex = 0, string keyPrefix = "language") where TLocalizationResource : LocalizationResourceBase
        {
            ArgumentNullException.ThrowIfNull(systemName, "systemName");
            ArgumentNullException.ThrowIfNull(keyPrefix, "keyPrefix");
            systemName = systemName.ToLower();
            keyPrefix = keyPrefix.ToLowerInvariant();
            RedisResourceOptions redisResourceOptions = new RedisResourceOptions(systemName, dbIndex, keyPrefix);
            string key = redisResourceOptions.ToString();
            CTPRedisLocalizationResource CTPRedisLocalizationResource;
            if (Resources.TryGetValue(key, out CTPRedisLocalizationResource value))
            {
                CTPRedisLocalizationResource = value;
            }
            else
            {
                ILoggerFactory factory = LoggerFactory.Create(delegate (ILoggingBuilder l)
                {
                    l.AddConsole();
                });
                ILogger<RedisClient> logger = factory.CreateLogger<RedisClient>();
                RedisClient redisClient = RedisHelper.Create(delegate (ConnectionStringBuilder builder)
                {
                    builder.Prefix = null;
                    builder.Database = dbIndex;
                }, delegate (object? s, NoticeEventArgs e)
                {
                    logger.LogDebug(e.Log);
                });
                CTPRedisLocalizationResource = new CTPRedisLocalizationResource(redisClient, redisResourceOptions);
                Resources[key] = CTPRedisLocalizationResource;
            }

            localizationResource.Contributors.Add(CTPRedisLocalizationResource);
            return localizationResource;
        }
    }
}
